package userHelp

import (
	myConfig "common/config"
	"common/helper"
	myredis "common/redis"
	"encoding/json"
	"fmt"
	"math/rand"
	"sort"
	"strconv"
	"time"
)

type TblMemberDisbindArea struct {
	Uid              string `json:"uid" db:"uid" cbor:"uid"`
	CfgType          int    `json:"cfgType" db:"cfgType" cbor:"cfgType"`                                  //0未配置  1 玩家配置 2 代理配置 3 系统
	CfgInviteBase    int    `json:"cfg_Invite_base" db:"cfg_Invite_base" cbor:"cfg_Invite_base"`          //配置区间的起始人数
	CfgInviteCount   int    `json:"cfg_Invite_count" db:"cfg_Invite_count" cbor:"cfg_Invite_count"`       //配置区间的邀请人数
	CfgDisbindCounts int    `json:"cfg_disbind_counts" db:"cfg_disbind_counts" cbor:"cfg_disbind_counts"` //配置区间的掉绑人数

	TotalInviteCounts  int `json:"total_invite_counts" db:"total_invite_counts" cbor:"total_invite_counts"`    //已邀请人数 只累加做最后的判断
	TotalDisbindCounts int `json:"total_disbind_counts" db:"total_disbind_counts" cbor:"total_disbind_counts"` //已掉绑人数 只累加做最后的判断

	MinInviteCounts    int `json:"min_invite_counts" db:"min_invite_counts" cbor:"min_invite_counts"`          //小区间已邀请人数 区间任务完成需要清0
	MinDisbindCounts   int `json:"min_disbind_counts" db:"min_disbind_counts" cbor:"min_disbind_counts"`       //小区间已掉绑人数 区间任务完成需要清 0/1
	MinDisbindInterval int `json:"min_disbind_interval" db:"min_disbind_interval" cbor:"min_disbind_interval"` //小区间掉绑频率 CfgInviteCount/CfgDisbindCounts 并根据概率向上或向下取整
}

var g_tbl_member_disbind_area = "tbl_member_disbind_area:"

func SetCfgType(Uid string, CfgType int) {
	LoadUserToRedis(Uid)
	myredis.SetUserFieldValueByInt(Uid, g_tbl_member_disbind_area+"cfgType", CfgType)
}

func GetCfgType(Uid string) int {
	LoadUserToRedis(Uid)
	return myredis.GetUserFieldInt(Uid, g_tbl_member_disbind_area+"cfgType")
}

func SetCfgInviteBase(Uid string, result int) {
	LoadUserToRedis(Uid)
	myredis.SetUserFieldValueByInt(Uid, g_tbl_member_disbind_area+"cfg_Invite_base", result)
}

func GetCfgInviteBase(Uid string) int {
	LoadUserToRedis(Uid)
	return myredis.GetUserFieldInt(Uid, g_tbl_member_disbind_area+"cfg_Invite_base")
}

func SetCfgInviteCount(Uid string, result int) {
	LoadUserToRedis(Uid)
	myredis.SetUserFieldValueByInt(Uid, g_tbl_member_disbind_area+"cfg_Invite_count", result)
}

func GetCfgInviteCount(Uid string) int {
	LoadUserToRedis(Uid)
	return myredis.GetUserFieldInt(Uid, g_tbl_member_disbind_area+"cfg_Invite_count")
}

func SetCfgDisbindCounts(Uid string, result int) {
	LoadUserToRedis(Uid)
	myredis.SetUserFieldValueByInt(Uid, g_tbl_member_disbind_area+"cfg_disbind_counts", result)
}

func GetCfgDisbindCounts(Uid string) int {
	LoadUserToRedis(Uid)
	return myredis.GetUserFieldInt(Uid, g_tbl_member_disbind_area+"cfg_disbind_counts")
}

func AddTotalDisbindCounts(Uid string, inc int) {
	LoadUserToRedis(Uid)
	myredis.AddUserFieldValueByInt64(Uid, g_tbl_member_disbind_area+"total_disbind_counts", int64(inc))
}

func SetTotalDisbindCounts(Uid string, TotalDisbindCounts int) {
	LoadUserToRedis(Uid)
	myredis.SetUserFieldValueByInt(Uid, g_tbl_member_disbind_area+"total_disbind_counts", TotalDisbindCounts)
}

func GetTotalDisbindCounts(Uid string) int {
	LoadUserToRedis(Uid)
	return myredis.GetUserFieldInt(Uid, g_tbl_member_disbind_area+"total_disbind_counts")
}

func AddAreaTotalInviteCounts(Uid string, inc int) {
	LoadUserToRedis(Uid)
	myredis.AddUserFieldValueByInt64(Uid, g_tbl_member_disbind_area+"total_invite_counts", int64(inc))
}

func SetAreaTotalInviteCounts(Uid string, TotalInviteCounts int) {
	LoadUserToRedis(Uid)
	myredis.SetUserFieldValueByInt(Uid, g_tbl_member_disbind_area+"total_invite_counts", TotalInviteCounts)
}

func GetAreaTotalInviteCounts(Uid string) int {
	LoadUserToRedis(Uid)
	return myredis.GetUserFieldInt(Uid, g_tbl_member_disbind_area+"total_invite_counts")
}

func AddMinInviteCounts(Uid string, inc int) {
	LoadUserToRedis(Uid)
	myredis.AddUserFieldValueByInt64(Uid, g_tbl_member_disbind_area+"min_invite_counts", int64(inc))
}

func SetMinInviteCounts(Uid string, result int) {
	LoadUserToRedis(Uid)
	myredis.SetUserFieldValueByInt(Uid, g_tbl_member_disbind_area+"min_invite_counts", result)
}

func GetMinInviteCounts(Uid string) int {
	LoadUserToRedis(Uid)
	return myredis.GetUserFieldInt(Uid, g_tbl_member_disbind_area+"min_invite_counts")
}

func AddMinDisbindCounts(Uid string, inc int) {
	LoadUserToRedis(Uid)
	myredis.AddUserFieldValueByInt64(Uid, g_tbl_member_disbind_area+"min_disbind_counts", int64(inc))
}

func SetMinDisbindCounts(Uid string, result int) {
	LoadUserToRedis(Uid)
	myredis.SetUserFieldValueByInt(Uid, g_tbl_member_disbind_area+"min_disbind_counts", result)
}

func GetMinDisbindCounts(Uid string) int {
	LoadUserToRedis(Uid)
	return myredis.GetUserFieldInt(Uid, g_tbl_member_disbind_area+"min_disbind_counts")
}

func SetMinDisbindInterval(Uid string, result int) {
	LoadUserToRedis(Uid)
	myredis.SetUserFieldValueByInt(Uid, g_tbl_member_disbind_area+"min_disbind_interval", result)
}

func GetMinDisbindInterval(Uid string) int {
	LoadUserToRedis(Uid)
	return myredis.GetUserFieldInt(Uid, g_tbl_member_disbind_area+"min_disbind_interval")
}

/*
重置小敬意
*/
func ResetMinArea(ParentId string) {

	CfgInviteCount := GetCfgInviteCount(ParentId)
	CfgDisbindCounts := GetCfgDisbindCounts(ParentId)

	SetMinInviteCounts(ParentId, 0)
	SetMinDisbindCounts(ParentId, 0)

	if CfgDisbindCounts != 0 {
		MinBase := CfgInviteCount / CfgDisbindCounts
		midMode := CfgInviteCount % CfgDisbindCounts

		//大区间转化成小区间 刚刚好
		if midMode == 0 {
			SetMinDisbindInterval(ParentId, MinBase)
		} else {
			minRate := int(float32(midMode) / float32(CfgDisbindCounts) * 10000)
			rand.New(rand.NewSource(time.Now().UnixNano()))
			randValue := rand.Intn(10000) + 1

			if randValue > minRate {
				SetMinDisbindInterval(ParentId, MinBase)
			} else {
				SetMinDisbindInterval(ParentId, MinBase+1)
			}
		}

	} else {
		SetMinDisbindInterval(ParentId, 0)
	}
}

/*
生重置用户 区间的掉绑信息
*/
func ResetDisableArea(ParentId string, CfgType int, CfgInviteBase int, CfgInviteCount int, CfgDisbindCounts int) {

	SetCfgType(ParentId, CfgType)
	SetCfgInviteBase(ParentId, CfgInviteBase)
	SetCfgInviteCount(ParentId, CfgInviteCount)
	SetCfgDisbindCounts(ParentId, CfgDisbindCounts)

	SetAreaTotalInviteCounts(ParentId, 0)
	SetTotalDisbindCounts(ParentId, 0)

	SetMinInviteCounts(ParentId, 0)
	SetMinDisbindCounts(ParentId, 0)
	ResetMinArea(ParentId)
}

/*
获取总的邀请人数(绑定+掉绑)
*/
func GetInviteAmountFromDB(ParentId string) int {
	SqlSelect := fmt.Sprintf("SELECT team_num FROM tbl_proxy_accu WHERE uid=%s and level=1", ParentId)
	var TotalInviteAmount int = 0

	err := myredis.GetSlaveDBInstance().Get(&TotalInviteAmount, SqlSelect)
	if err != nil {
		helper.SqlSelectErrLog("CanBindParent,%s,%s", err.Error(), SqlSelect)
	}

	SqlSelect = fmt.Sprintf("SELECT count(1) FROM tbl_proxy_base WHERE unbindParentId=%s ", ParentId)
	var unbindCount int = 0
	err = myredis.GetSlaveDBInstance().Get(&unbindCount, SqlSelect)
	if err != nil {
		helper.SqlSelectErrLog("CanBindParent,%s,%s", err.Error(), SqlSelect)
	}

	// 所有的邀请人数(包含掉绑的数据)
	TotalInviteAmount += unbindCount

	return TotalInviteAmount
}

func SetMemberDisableAreaInfo(ParentId string) {

	TotalInviteAmount := GetInviteAmountFromDB(ParentId)

	var disbindControl string = ""
	if G_UserButton.GetUnbind(ParentId) == 1 {
		disbindControl = G_UserButton.GetDisbindControl(ParentId)
	}

	OperatorId := GetMemberOperatorId(ParentId)

	if OperatorId == "" || OperatorId == "0" {
		OperatorId = myConfig.Def_Channel
	}

	var userUnBindList myConfig.UnbindItemSlice
	var personDisableCfg bool = false //个人是否有配置
	var CfgType int = 0               //无配置

	err := json.Unmarshal([]byte(disbindControl), &userUnBindList)

	if err == nil && len(userUnBindList) > 0 {
		personDisableCfg = true
		CfgType = 1 //使用自己的配置
	}

	//个人无配置 走渠道或系统
	if !personDisableCfg && G_UserButton.GetUnbind(ParentId) == 1 {
		for _, value := range myConfig.CfgDisableBindList {
			if OperatorId == strconv.Itoa(value.OperatorId) {
				var userItem myConfig.UserDisableBindItem
				userItem.CfgInviteBase = value.CfgInviteBase
				userItem.CfgInviteCount = value.CfgInviteCount
				userItem.CfgDisbindCounts = value.CfgDisbindCounts
				userUnBindList = append(userUnBindList, userItem)
				if OperatorId == myConfig.Def_Channel {
					CfgType = 3 ////使用系统配置
				} else {
					CfgType = 2 ////使用代理的配置
				}

			}
		}
	}

	sort.Stable(userUnBindList)

	var CfgInviteBase int = 0
	var CfgInviteCount int = 0
	var CfgDisbindCounts int = 0
	for _, value := range userUnBindList {
		if TotalInviteAmount >= value.CfgInviteBase &&
			TotalInviteAmount < value.CfgInviteBase+value.CfgInviteCount {
			CfgInviteBase = value.CfgInviteBase
			CfgInviteCount = value.CfgInviteCount
			CfgDisbindCounts = value.CfgDisbindCounts
			break
		}
	}

	//四个有一个不一样 重置大区间  可能配置被修改
	if CfgType != GetCfgType(ParentId) ||
		CfgInviteBase != GetCfgInviteBase(ParentId) ||
		CfgInviteCount != GetCfgInviteCount(ParentId) ||
		CfgDisbindCounts != GetCfgDisbindCounts(ParentId) {
		ResetDisableArea(ParentId, CfgType, CfgInviteBase, CfgInviteCount, CfgDisbindCounts)
	}

	//  大区间任务完成
	AreaTotalInviteAmount := GetAreaTotalInviteCounts(ParentId)
	CfgInviteCount = GetCfgInviteCount(ParentId)

	if AreaTotalInviteAmount > 0 && AreaTotalInviteAmount >= CfgInviteCount {
		ResetDisableArea(ParentId, CfgType, CfgInviteBase, CfgInviteCount, CfgDisbindCounts)
	}

	//小区间任务完成
	MinDisbindCounts := GetMinDisbindCounts(ParentId)
	MinInviteCounts := GetMinInviteCounts(ParentId)
	MinDisbindInterval := GetMinDisbindInterval(ParentId)
	if MinDisbindCounts >= 1 && MinInviteCounts >= MinDisbindInterval {
		ResetMinArea(ParentId)
	}
}
func CanBindParent(ParentId string) bool {

	if myConfig.GetGameCfgInt(myConfig.CfgGlobaForbidlUnbind) == 1 {
		return true
	}

	//设置玩家掉绑的区间信息
	SetMemberDisableAreaInfo(ParentId)

	CfgType := GetCfgType(ParentId)
	CfgInviteCount := GetCfgInviteCount(ParentId)
	CfgDisbindCounts := GetCfgDisbindCounts(ParentId)

	//参数不对 不掉绑
	if CfgType == 0 || CfgInviteCount == 0 || CfgDisbindCounts == 0 {
		return true
	}

	TotalInviteCounts := GetAreaTotalInviteCounts(ParentId)
	TotalDisbindCounts := GetTotalDisbindCounts(ParentId)

	//剩下的人少于未掉绑的人 必掉绑
	if CfgInviteCount-TotalInviteCounts <= CfgDisbindCounts-TotalDisbindCounts {
		return false
	}

	//掉绑人数已经到了 不掉绑
	if TotalDisbindCounts == CfgDisbindCounts {
		return true
	}

	//以下判断小区间
	MinInviteCounts := GetMinInviteCounts(ParentId)
	MinDisbindCounts := GetMinDisbindCounts(ParentId)
	MinDisbindInterval := GetMinDisbindInterval(ParentId)

	if MinDisbindCounts == 0 { // 未掉绑
		//小区间内最后一个 必掉绑
		if MinInviteCounts+1 == MinDisbindInterval {
			return false
		} else {
			//有概率掉绑
			rand.New(rand.NewSource(time.Now().UnixNano()))
			randValue := rand.Intn(100000000) + 1

			var DisableBindRate int = 0
			if MinDisbindInterval == MinInviteCounts {
				DisableBindRate = 0
			} else {
				DisableBindRate = 100000000 / (MinDisbindInterval - MinInviteCounts)
			}

			if randValue > DisableBindRate {
				return true
			} else {
				return false
			}
		}
	} else {
		return true
	}
}
